﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Playwright;

namespace BrowserCollect;

public static class BrowserContextExtension
{
    /// <summary>
    /// 清除指定域名的所有cookies
    /// </summary>
    /// <param name="context"></param>
    /// <param name="domains"></param>
    public static async Task ClearCookiesByDomainAsync(this IBrowserContext context, params string[] domains)
    {
        var filteredCookies = (await context.CookiesAsync())
            .Where(c => !domains.Any(d => c.Domain.Contains(d))).ToArray();
        await context.ClearCookiesAsync();
        await context.AddCookiesAsync(filteredCookies.Select(c => new Cookie()
        {
            Domain = c.Domain,
            Expires = c.Expires,
            HttpOnly = c.HttpOnly,
            Name = c.Name,
            Path = c.Path,
            SameSite = c.SameSite,
            Secure = c.Secure,
            Value = c.Value,
        }));
    }

    /// <summary>
    /// 获取当前page的cookie下指定名称的值
    /// </summary>
    /// <param name="page"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public static Task<string?> GetCookieValueByName(this IPage page, string name) =>
        page.Context.GetCookieValueByName(page.Url, name);

    /// <summary>
    /// 获取url下cookie指定名称的值
    /// </summary>
    /// <param name="context"></param>
    /// <param name="url"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public static async Task<string?> GetCookieValueByName(this IBrowserContext context, string url, string name)
    {
        return (await context.CookiesAsync(new[] { url })).Where(c => c.Name == name).Select(c => c.Value).FirstOrDefault();
    }
    
    /// <summary>
    /// 确保会话cookie在浏览器关闭时不过期, 以供下次打开浏览器使用
    /// </summary>
    /// <param name="context"></param>
    public static async Task EnsureSessionCookieNotExpired(this IBrowserContext context)
    {
        var oneYearLater = (float)DateTime.UtcNow.AddYears(1).Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
        var allCookies = await context.CookiesAsync();
        await context.ClearCookiesAsync();
        await context.AddCookiesAsync(allCookies.Select(c => new Cookie()
        {
            Domain = c.Domain,
            Expires = c.Expires == -1 ? oneYearLater : c.Expires,
            HttpOnly = c.HttpOnly,
            Name = c.Name,
            Path = c.Path,
            SameSite = c.SameSite,
            Secure = c.Secure,
            Value = c.Value,
        }));
    }

    /// <summary>
    /// 确保会话cookie在浏览器关闭时不过期, 以供下次打开浏览器使用
    /// </summary>
    /// <param name="context"></param>
    /// <param name="cookies"></param>
    public static async Task EnsureSessionCookieNotExpired(this IBrowserContext context, IEnumerable<BrowserContextCookiesResult> cookies)
    {
        var oneYearLater = (float)DateTime.UtcNow.AddYears(1).Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
        await context.ClearCookiesAsync();
        await context.AddCookiesAsync(cookies.Select(c => new Cookie()
        {
            Domain = c.Domain,
            Expires = c.Expires == -1 ? oneYearLater : c.Expires,
            HttpOnly = c.HttpOnly,
            Name = c.Name,
            Path = c.Path,
            SameSite = c.SameSite,
            Secure = c.Secure,
            Value = c.Value,
        }));
    }
}